package com.ts.api.module.api.convert.receive.http;

import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.valid.ValidParam;
import com.ts.api.common.constant.api.ApiBizTypeEnum;
import com.ts.api.common.constant.api.ApiProviderEnum;
import com.ts.api.module.api.convert.core.http.client.ApiHttpExecutor;
import com.ts.api.module.api.convert.core.http.client.ApiHttpMessage;
import com.ts.api.module.api.convert.core.http.client.ApiHttpRequestConfigure;
import com.ts.api.module.api.convert.receive.context.ApiReceiveNoticeConvertContext;
import com.ts.api.module.api.convert.receive.context.ApiReceivePhoneMd5ConvertContext;
import com.ts.api.module.api.convert.receive.entity.ApiReceiveNotice;
import com.ts.api.module.api.convert.receive.handler.ApiReceiveNoticeHandler;
import com.ts.api.module.api.convert.receive.handler.ApiReceivePhoneMd5ConvertHandler;
import com.ts.api.module.api.entity.po.ApiKeyPO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 *  渠道通知类HTTP处理器
 *
 *  @author Pan
 */
@Component
public class ApiReceiveNoticeHttpHandler {

    @Autowired
    private ApiHttpExecutor apiHttpExecutor;
    @Autowired
    private ApiReceiveNoticeConvertContext apiReceiveNoticeConvertContext;
    @Autowired
    private ApiReceivePhoneMd5ConvertContext apiReceivePhoneMd5ConvertContext;
    @Autowired
    private ApiHttpRequestConfigure apiHttpRequestConfigure;

    /**
     *  发送主动推送进件成功类型请求
     *
     *  @param  apiKeyPO            ApiKey渠道实体
     *  @param  apiReceiveNotice    发送API消息实体类
     *  @return ApiHttpMessage
     */
    public ApiHttpMessage sendPushApplyNotice(ApiKeyPO apiKeyPO, ApiReceiveNotice apiReceiveNotice) {
        String apiClientId = apiKeyPO.getApiClientId();

        //  根据拉取或者推送业务类型获取消息对象-如果地址为空则不发送消息
        String apiPushNotifyUrl = apiKeyPO.getApiNotifyUrl();
        if (ValidParam.isEmpty(apiPushNotifyUrl)) {
            return null;
        }

        //  进件成功主动推送通知
        ApiHttpMessage httpMessage = ApiHttpMessage.create(apiPushNotifyUrl, ApiBizTypeEnum.PUSH_APPLY_NOTICE);
        try {
            //  设置请求基本参数
            String extendUrl = apiReceiveNotice.getExtendUrl();
            //  替换url
            if (ValidParam.isNotNull(extendUrl)) {
                httpMessage.setUrl(httpMessage.getUrl() + extendUrl);
            }
            httpMessage.setHttpContentType(apiReceiveNotice.getHttpContentType());
            httpMessage.setHttpRequestHeader(apiReceiveNotice.getHttpRequestHeader());
            httpMessage.setDisableUrlEncode(apiReceiveNotice.getDisableUrlEncode());
            httpMessage.setReqId(Long.valueOf(apiReceiveNotice.getReqId()));
            httpMessage.setPhoneMd5(apiReceiveNotice.getPhoneMd5());

            //  接入标识
            Integer apiAccessProviderType = apiKeyPO.getApiAccessProviderType();
            //  我方接入-进件成功主动推送通知
            if (ApiProviderEnum.WE.hasType(apiAccessProviderType)) {
                ApiReceivePhoneMd5ConvertHandler receiveEvent = apiReceivePhoneMd5ConvertContext.getReceive(apiClientId);
                //  构建请求对象
                Object sendBody = receiveEvent.reqPushApplyNotice(apiReceiveNotice);
                httpMessage.setRequestBody(sendBody);
                return sendReceiveApplyNotice(httpMessage, receiveEvent);
            }

            //  对方接入-进件成功主动推送通知
            if (ApiProviderEnum.OTHER.hasType(apiAccessProviderType)) {
                ApiReceiveNoticeHandler defaultPushApplyNotice = apiReceiveNoticeConvertContext.getDefaultPushApplyNotice();
                //  构建请求对象
                Object sendBody = defaultPushApplyNotice.buildRequest(apiReceiveNotice);
                httpMessage.setRequestBody(sendBody);
                return sendNotice(httpMessage, defaultPushApplyNotice);
            }
            return null;
        } catch (Exception e) {
            //  进件时转换时出现异常
            httpMessage.setExceptionInfo(e);
            return httpMessage;
        }
    }

    /**
     *  发送拉取获取进件通知类型请求
     *
     *  @param  apiKeyPO            ApiKey渠道实体
     *  @param  apiReceiveNotice    发送API消息实体类
     *  @return ApiHttpMessage
     */
    public ApiHttpMessage sendPullApplyNotice(ApiKeyPO apiKeyPO, ApiReceiveNotice apiReceiveNotice) {
        String apiClientId = apiKeyPO.getApiClientId();

        //  根据拉取或者推送业务类型获取消息对象-如果地址为空则不发送消息
        String apiPullApplyNotifyUrl = apiKeyPO.getApiPullApplyNotifyUrl();
        if (ValidParam.isEmpty(apiPullApplyNotifyUrl)) {
            return null;
        }

        //  发送拉取获取进件通知类型请求
        ApiHttpMessage httpMessage = ApiHttpMessage.create(apiPullApplyNotifyUrl, ApiBizTypeEnum.PULL_APPLY_NOTICE);
        try {
            //  设置请求基本参数
            String extendUrl = apiReceiveNotice.getExtendUrl();
            //  替换url
            if (ValidParam.isNotNull(extendUrl)) {
                httpMessage.setUrl(httpMessage.getUrl() + extendUrl);
            }
            httpMessage.setHttpContentType(apiReceiveNotice.getHttpContentType());
            httpMessage.setHttpRequestHeader(apiReceiveNotice.getHttpRequestHeader());
            httpMessage.setDisableUrlEncode(apiReceiveNotice.getDisableUrlEncode());
            httpMessage.setReqId(Long.valueOf(apiReceiveNotice.getReqId()));
            httpMessage.setPhoneMd5(apiReceiveNotice.getPhoneMd5());

            //  接入标识
            Integer apiAccessProviderType = apiKeyPO.getApiAccessProviderType();
            //  我方接入-进件成功主动推送通知
            if (ApiProviderEnum.WE.hasType(apiAccessProviderType)) {
                ApiReceivePhoneMd5ConvertHandler receiveEvent = apiReceivePhoneMd5ConvertContext.getReceive(apiClientId);
                //  构建请求对象
                Object sendBody = receiveEvent.reqPullApplyNotice(apiReceiveNotice);
                httpMessage.setRequestBody(sendBody);
                return sendReceiveApplyNotice(httpMessage, receiveEvent);
            }

            //  对方接入-拉取进件申请回调
            if (ApiProviderEnum.OTHER.hasType(apiAccessProviderType)) {
                ApiReceiveNoticeHandler defaultPullApplyNotice = apiReceiveNoticeConvertContext.getDefaultPullApplyNotice();
                Object sendBody = defaultPullApplyNotice.buildRequest(apiReceiveNotice);
                httpMessage.setRequestBody(sendBody);
                return sendNotice(httpMessage, defaultPullApplyNotice);
            }
            return null;
        } catch (Exception e) {
            //  进件时转换时出现异常
            httpMessage.setExceptionInfo(e);
            return httpMessage;
        }
    }

    /**
     *  发送通知类请求
     *
     *  @param  httpMessage                    http返回消息
     *  @param  apiReceivePhoneMd5ConvertHandler        通知类事件
     *  @return ApiHttpMessage
     */
    ApiHttpMessage sendReceiveApplyNotice(ApiHttpMessage httpMessage, ApiReceivePhoneMd5ConvertHandler apiReceivePhoneMd5ConvertHandler) throws Exception {
        apiHttpExecutor.execute(httpMessage);
        String responseBody = httpMessage.getResponseBody();

        //  验证非空情况
        if (ValidParam.isEmpty(responseBody) || ValidParam.isNotEmpty(httpMessage.getErrorMsg()) || httpMessage.hasReqTimeout()) {
            httpMessage.setHasSuc(false);
            return httpMessage;
        }

        //  验证业务返回消息
        boolean hasSuc = false;
        ApiBizTypeEnum apiBizTypeEnum = httpMessage.getApiBizTypeEnum();

        //  拉取进件通知
        if (Eq.enums(ApiBizTypeEnum.PULL_APPLY_NOTICE, apiBizTypeEnum)) {
            hasSuc = apiReceivePhoneMd5ConvertHandler.respPullApplyNotice(responseBody);
        }
        //  主动推送进件通知
        if (Eq.enums(ApiBizTypeEnum.PUSH_APPLY_NOTICE, apiBizTypeEnum)) {
            hasSuc = apiReceivePhoneMd5ConvertHandler.respPushApplyNotice(responseBody);
        }
        httpMessage.setHasSuc(hasSuc);
        httpMessage.setResponseBody(responseBody);
        return httpMessage;
    }

    /**
     *  发送通知类请求
     *
     *  @param  httpMessage                    http返回消息
     *  @param  apiReceiveNoticeHandler     通知类事件
     *  @return ApiHttpMessage
     */
    ApiHttpMessage sendNotice(ApiHttpMessage httpMessage, ApiReceiveNoticeHandler apiReceiveNoticeHandler) throws Exception {
        apiHttpExecutor.execute(httpMessage);

        String responseBody = httpMessage.getResponseBody();
        //  验证业务返回消息
        boolean hasSuc = apiReceiveNoticeHandler.hasSuc(responseBody);
        httpMessage.setHasSuc(hasSuc);
        httpMessage.setResponseBody(responseBody);
        return httpMessage;
    }
}
